package com.scau402.system1.service.assembler;

import com.scau402.system.domain.WmsBasicClient;
import com.scau402.system.domain.WmsBasicProcessor;
import com.scau402.system.domain.WmsBasicSupplier;
import com.scau402.system1.domain.bo.*;
import com.scau402.system1.domain.vo.WmsInboundJadeVO;
import com.scau402.system1.domain.vo.WmsInboundOrderDetailVO;
import com.scau402.system1.domain.vo.WmsInboundOrderVO;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 商品入库单VO组装器
 *
 * @author
 * @create 2024/1/3 15:25
 * @description
 */
@Slf4j
@Component
public class WmsInboundVOAssembler {

    public List<WmsInboundOrderVO> toInboundOrderVOList(List<WmsInboundOrderBO> inboundOrderBOList, Map<String, List<WmsJadeBO>> jadeBOMap, Map<Long, WmsBasicSupplier> supplierMap, Map<Long, WmsBasicClient> clientMap, Map<Long, WmsBasicProcessor> processorMap, Map<Long, WmsWarehouseBO> warehouseBOMap) {
        return inboundOrderBOList.stream()
                .filter(Objects::nonNull)
                .map(bo -> toInboundOrderVO(bo, jadeBOMap.get(bo.getOrderCode()), supplierMap.get(bo.getSupplierId()), clientMap.get(bo.getClientId()), processorMap.get(bo.getProcessorId()), warehouseBOMap.get(bo.getDesWarehouseId())))
                .collect(Collectors.toList());
    }

    public WmsInboundOrderVO toInboundOrderVO(WmsInboundOrderBO inboundOrderBO, List<WmsJadeBO> jadeBOList, WmsBasicSupplier supplier, WmsBasicClient client, WmsBasicProcessor processor, WmsWarehouseBO warehouseBO) {
        WmsInboundOrderVO orderVO = new WmsInboundOrderVO();

        // 入库单主表
        if (Objects.isNull(inboundOrderBO)) {
            log.warn("入库单主表为空，无法组装WmsInboundOrderVO");
            return orderVO;
        }
        BeanUtils.copyProperties(inboundOrderBO, orderVO);
        if (Objects.nonNull(inboundOrderBO.getOrderDate())) {
            orderVO.setOrderDate(inboundOrderBO.getOrderDate().toString());
        }
        if (Objects.nonNull(inboundOrderBO.getValidDate())) {
            orderVO.setValidDate(inboundOrderBO.getValidDate().toString());
        }
        orderVO.setOrderType(inboundOrderBO.getOrderTypeValue());

        // 供应商
        if (Objects.isNull(supplier)) {
            log.warn("供应商为空，无法组装WmsInboundOrderVO的供应商信息, 入库单id: {}", inboundOrderBO.getId());
        } else {
            orderVO.setSupplierId(supplier.getId());
            orderVO.setSupplierCode(supplier.getSupplierCode());
            orderVO.setSupplierName(supplier.getSupplierName());
            orderVO.setSupplierType(supplier.getSupplierType());
        }

        // 客户
        if (Objects.isNull(client)) {
            log.warn("客户为空，无法组装WmsInboundOrderVO的客户信息, 入库单id: {}", inboundOrderBO.getId());
        } else {
            orderVO.setClientId(client.getId());
            orderVO.setClientCode(client.getClientCode());
            orderVO.setClientName(client.getClientName());
            orderVO.setClientType(client.getClientType());
        }

        // 仓库
        if (Objects.isNull(warehouseBO)) {
            log.warn("仓库为空，无法组装WmsInboundOrderVO的仓库信息, 入库单id: {}", inboundOrderBO.getId());
        } else {
            orderVO.setWarehouseId(warehouseBO.getId());
            orderVO.setWarehouseCode(warehouseBO.getWarehouseCode());
            orderVO.setWarehouseName(warehouseBO.getWarehouseName());

            // 仓位
            Set<String> storageNameList = Optional.ofNullable(inboundOrderBO.getWmsInboundOrderDetailBOList())
                    .orElse(new ArrayList<>(0))
                    .stream()
                    .filter(Objects::nonNull)
                    .map(WmsInboundOrderDetailBO::getDesStorageId)
                    .filter(Objects::nonNull)
                    .map(storageId -> Optional.ofNullable(warehouseBO.getStorageMap().get(storageId))
                            .map(WmsWarehouseStorageBO::getStorageName)
                            .orElse("未知仓位名称"))
                    .collect(Collectors.toSet());
            orderVO.setStorageName(String.join(",", storageNameList));
        }


        // 加工厂
        if (Objects.isNull(processor)) {
            log.warn("加工厂为空，无法组装WmsInboundOrderVO的加工厂信息, 入库单id: {}", inboundOrderBO.getId());
        } else {
            orderVO.setProcessorId(processor.getId());
            orderVO.setProcessorCode(processor.getProcessorCode());
            orderVO.setProcessorName(processor.getProcessorName());
            orderVO.setProcessorType(processor.getProcessorType());
        }

        // 玉石
        if (Collections.isEmpty(jadeBOList)) {
            log.warn("翡翠为空，无法组装WmsInboundOrderVO的翡翠信息, 入库单id: {}", inboundOrderBO.getId());
        } else if (Objects.isNull(warehouseBO)) {
            log.warn("仓库为空，无法组装WmsInboundOrderVO的翡翠信息, 入库单id: {}", inboundOrderBO.getId());
        } else {
            orderVO.setWmsInboundOrderDetailVOList(toInboundDetailVOList(jadeBOList, inboundOrderBO.getWmsInboundOrderDetailBOList(), warehouseBO.getStorageMap()));
            orderVO.setJadeQuantity(jadeBOList.size());
            BigDecimal jadeTotalCostPrice = new BigDecimal("0.0");
            jadeTotalCostPrice = jadeBOList.stream()
                    .filter(Objects::nonNull)
                    .map(WmsJadeBO::getJadeCost)
                    .filter(Objects::nonNull)
                    .reduce(jadeTotalCostPrice, BigDecimal::add)
                    .setScale(2, RoundingMode.HALF_UP);
//            orderVO.setJadeTotalCostPrice(jadeTotalCostPrice.floatValue());
            orderVO.setJadeTotalCostPrice(jadeTotalCostPrice);
        }

        // 计算总成本价
        orderVO.setTotalCost(
                orderVO.getWmsInboundOrderDetailVOList() == null ? 0 :
                        orderVO.getWmsInboundOrderDetailVOList().stream()
                                .mapToDouble(item -> {
                                    try {
                                        return Double.parseDouble(item.getJadeCost());
                                    } catch (Exception ignore) {
                                        return 0;
                                    }
                                })
                                .sum()
        );

        return orderVO;
    }

    private static List<WmsInboundOrderDetailVO> toInboundDetailVOList(List<WmsJadeBO> jadeBOList, List<WmsInboundOrderDetailBO> wmsInboundOrderDetailBOList, Map<Long, WmsWarehouseStorageBO> storageMap) {
        return wmsInboundOrderDetailBOList.stream()
                .filter(Objects::nonNull)
                .map(bo -> {
                    WmsInboundOrderDetailVO vo = new WmsInboundOrderDetailVO();

                    // 入库单明细
                    vo.setId(bo.getId());
                    vo.setInboundOrderCode(bo.getInboundOrderCode());
                    vo.setOutboundOrderDetailId(bo.getOutboundOrderDetailId());
                    vo.setOutboundOrderDetailCode(bo.getOutboundOrderDetailCode());
                    vo.setDelFlag(bo.getDelFlag());
                    vo.setRemark(bo.getRemark());

                    // 仓位
                    WmsWarehouseStorageBO storageBO = storageMap.get(bo.getDesStorageId());
                    if (Objects.isNull(storageBO)) {
                        log.warn("仓位不存在，无法组装WmsInboundOrderDetailVO, 入库单id：{}，入库单明细id：{}， 仓位id：{}", bo.getInboundOrderCode(), bo.getId(), bo.getDesStorageId());
                    } else {
                        vo.setStorageId(storageBO.getId());
                        vo.setStorageCode(storageBO.getStorageCode());
                        vo.setStorageName(storageBO.getStorageName());
                    }

                    // 玉石
                    Map<Long, WmsJadeBO> jadeBOMap = jadeBOList.stream().collect(Collectors.toMap(WmsJadeBO::getId, Function.identity()));
                    WmsJadeBO jadeBO = jadeBOMap.get(bo.getJadeId());
                    if (Objects.isNull(jadeBO)) {
                        log.warn("玉石不存在，无法组装WmsInboundOrderDetailVO, 入库单id：{}，入库单明细id：{}， 玉石id：{}", bo.getInboundOrderCode(), bo.getId(), bo.getJadeId());
                    } else {
                        vo.setJadeId(jadeBO.getId());
                        vo.setJadeCode(jadeBO.getJadeCode());
                        vo.setJadeName(jadeBO.getJadeName());
                        vo.setJadeTypeId(jadeBO.getJadeTypeBO().getId());
                        vo.setJadeTypeName(jadeBO.getJadeTypeBO().getJadeTypeName());
                        vo.setJadeBarcode(jadeBO.getJadeBarcode());
                        if (Objects.nonNull(jadeBO.getJadeCost())) {
                            vo.setJadeCost(jadeBO.getJadeCost().toString());
                        }
                        if (Objects.nonNull(jadeBO.getJadeTagPrice())) {
                            vo.setJadeTagPrice(jadeBO.getJadeTagPrice().toString());
                        }
                        if (Objects.nonNull(jadeBO.getJadeMarketPrice())) {
                            vo.setJadeMarketPrice(jadeBO.getJadeMarketPrice().toString());
                        }
                        if (Objects.nonNull(jadeBO.getJadeSupplyPrice())) {
                            vo.setJadeSupplyPrice(jadeBO.getJadeSupplyPrice().toString());
                        }
                        vo.setJadeCostCipher(jadeBO.getJadeCostCipher());
                        vo.setJadeTagPriceCipher(jadeBO.getJadeTagPriceCipher());
                        vo.setCiphertextId(jadeBO.getCiphertextId());
                        vo.setImageId(jadeBO.getImageId());
                    }
                    return vo;
                }).collect(Collectors.toList());

    }

    public List<WmsInboundJadeVO> toInboundJadeVOList(List<WmsJadeBO> jadeBOList, Map<String, String> inboundOrderTypeMap, Map<Long, WmsWarehouseBO> warehouseBOMap, Map<Long, WmsWarehouseStorageBO> warehouseStorageBOMap) {
        return jadeBOList.stream()
                .filter(Objects::nonNull)
                .map(jadeBO -> {
                    WmsInboundJadeVO vo = new WmsInboundJadeVO();

                    // 玉石
                    vo.setJadeId(jadeBO.getId());
                    vo.setInboundOrderCode(jadeBO.getOrderCode());
                    vo.setJadeTypeId(jadeBO.getJadeTypeBO().getId());
                    vo.setJadeTypeName(jadeBO.getJadeTypeBO().getJadeTypeName());
                    vo.setJadeCode(jadeBO.getJadeCode());
                    vo.setJadeName(jadeBO.getJadeName());
                    vo.setJadeBarcode(jadeBO.getJadeBarcode());
                    if (Objects.nonNull(jadeBO.getJadeCost())) {
                        vo.setJadeCost(jadeBO.getJadeCost().toString());
                    }
                    if (Objects.nonNull(jadeBO.getJadeTagPrice())) {
                        vo.setJadeTagPrice(jadeBO.getJadeTagPrice().toString());
                    }
                    vo.setJadeCostCipher(jadeBO.getJadeCostCipher());
                    vo.setJadeTagPriceCipher(jadeBO.getJadeTagPriceCipher());
                    vo.setImageId(jadeBO.getImageId());
                    vo.setRemark(jadeBO.getRemark());
                    vo.setCreateBy(jadeBO.getCreateBy());
                    vo.setCreateTime(jadeBO.getCreateTime());
                    // 入库类型
                    vo.setOrderType(inboundOrderTypeMap.get(jadeBO.getOrderCode()));

                    // 仓库
                    WmsWarehouseBO warehouseBO = warehouseBOMap.get(jadeBO.getWarehouseId());
                    if (Objects.isNull(warehouseBO)) {
                        log.warn("仓库不存在，无法组装WmsInboundJadeVO, 玉石id：{}，仓库id：{}", jadeBO.getId(), jadeBO.getWarehouseId());
                    } else {
                        vo.setWarehouseId(warehouseBO.getId());
                        vo.setWarehouseCode(warehouseBO.getWarehouseCode());
                        vo.setWarehouseName(warehouseBO.getWarehouseName());
                    }

                    // 仓位
                    WmsWarehouseStorageBO storageBO = warehouseStorageBOMap.get(jadeBO.getStorageId());
                    if (Objects.isNull(storageBO)) {
                        log.warn("仓位不存在，无法组装WmsInboundJadeVO, 玉石id：{}，仓位id：{}", jadeBO.getId(), jadeBO.getStorageId());
                    } else {
                        vo.setStorageId(storageBO.getId());
                        vo.setStorageCode(storageBO.getStorageCode());
                        vo.setStorageName(storageBO.getStorageName());
                    }

                    return vo;
                })
                .collect(Collectors.toList());
    }
}
